#!/usr/bin/python
import re
import collections

class SitesPlugin:
    """
    Match
    #define GUID_######## "########" /* This is comments. */
    """
    reg_guid_definition = '\#define GUID\_[A-Z]{1,8}\s+\"[A-Z]{1,8}\"\s+\/\* .+ \*\/'
    
    """
    Match 
    { "HTTP", "User-Agent", "*****.***", GUID_########, 1 },
    { "TLS", "Host", "*****.***", GUID_########, 0 },
    """
    reg_rule = '\{ \"(HTTP|TLS)\"\, \"(Host|Referer)\"\, \"(.+)\"\, (GUID\_[A-Z]{1,8})\, [01] \}\,'
    
    def valid_guid_definition(self, definition):
        return re.match(SitesPlugin.reg_guid_definition, definition) != None or False
        
    def valid_rules(self, rule):
        return re.match(SitesPlugin.reg_rule, rule) != None or False

    def format_pattern_sites(self, header, pattern, http, tls, guid):
        output = "Sites, " + header + ", " + pattern + ", " + http + ", " + tls + ", " + guid + ", n,"
        return output
    
    def format_pattern_ads_sites(self, header, pattern, http, tls, guid):
        output = "Sites, " + header + ", " + pattern + ", " + http + ", " + tls + ", " + guid + ", y, Inspect HTTP referers for subclassification"
        return output

    def format_guid(self, guid):
        if guid.find('GUID_'):
            return 'GUID_' + str(guid).upper().strip()
        return guid.upper().strip()
    
    def parse_rule(self, rule):
        """
        Make a rule like { "HTTP", "Host", "naver.com", GUID_NAVER, 0 }, --> ['Host', 'naver.com', 'y', 'n', 'GUID_NAVER']
        
        Arguments:
        rule -- string, { "HTTP", "Host", "naver.com", GUID_NAVER, 0 },
        
        Returns:
        list -- a list consist of header, rule, http, tls, guid
        
        """
        pattern = []
        parsed_list = re.match(SitesPlugin.reg_rule, rule)
        pattern.append(parsed_list.group(2))    # header
        pattern.append(parsed_list.group(3))    # rule
        if (parsed_list.group(1) == "HTTP"):
            pattern.append("y")                 # http
            pattern.append("n")                 # tls
        else:
            pattern.append("n")                 # http
            pattern.append("y")                 # tls
        pattern.append(parsed_list.group(4))    # guid
        return pattern
    
    def make_webpattern_no_foi(self, rules_file, guids_file, output_file):
        """
        Make web pattern 
        { "HTTP", "Host", "*.naver.com", GUID_NAVER, 0 },
        { "TLS", "Host", "*.naver.com", GUID_NAVER, 0 },
        --->    Sites, Host, *.naver.com, y, y, GUID_NAVER, n,
        
        Arguments:
        rules_file -- file contains all rules like { "HTTP", "Host", "*.naver.com", GUID_NAVER, 0 },
        guids_file -- file contains all guids like GUID_NAVER or NAVER
        output_file -- file output file path
        
        Returns:
        None
        
        """
        rules_f = open(rules_file, "r")
        guids_f = open(guids_file, "r")
        guid_list = guids_f.readlines()
        rules_list = rules_f.readlines()
        dictionary = collections.OrderedDict()
        for line in rules_list:
            for guid in guid_list:
                if line.find(self.format_guid(guid)) >= 0 :
                    rule = self.parse_rule(line.strip())
                    # if this is http, add it
                    if (rule[2] == 'y'):
                        dictionary[rule[1]] = rule
                    # if this is tls, check if there is a exit rule, if there is then change tls to "y", if not then add it
                    else:
                        if (dictionary.has_key(rule[1])):
                            temp_list = dictionary.get(rule[1])
                            temp_list[2] = "y" # http
                            temp_list[3] = "y" # tls
                            dictionary[rule[1]] = temp_list
                        else:
                            dictionary[rule[1]] = rule
        
        with open(output_file,'w+') as file_w:
            for temp_list in sorted(dictionary.values(), key=lambda value:value[4][5]):
                pattern = self.format_pattern_sites(temp_list[0], # header
                                                    temp_list[1], # rule
                                                    temp_list[2], # http
                                                    temp_list[3], # tls
                                                    temp_list[4]) # guid
                file_w.write(pattern + "\n");
        guids_f.close()
        rules_f.close()
        file_w.close();
        
    def make_webpattern_ads_sites(self, rules_file, guids_file, output_file):
        """
        Make web pattern 
        { "HTTP", "Host", "*.naver.com", GUID_NAVER, 0 },
        --->    Sites, Host, *.naver.com, y, n, GUID_NAVER, y, Inspect HTTP referers for subclassification
        { "TLS", "Host", "*.naver.com", GUID_NAVER, 0 },
        --->    Sites, Host, *.naver.com, n, y, GUID_NAVER, n,
        
        Arguments:
        rules_file -- file contains all rules like { "HTTP", "Host", "*.naver.com", GUID_NAVER, 0 },
        guids_file -- file contains all guids like GUID_NAVER or NAVER
        output_file -- file output file path
        
        Returns:
        None
        
        """
        rules_f = open(rules_file, "r")
        guids_f = open(guids_file, "r")
        guid_list = guids_f.readlines()
        rules_list = rules_f.readlines()
        dictionary = collections.OrderedDict()
        for line in rules_list:
            for guid in guid_list:
                if line.find(self.format_guid(guid)) >= 0 :
                    rule = self.parse_rule(line.strip())
                    dictionary[rule[1] + rule[2] + rule[3]] = rule
        
        with open(output_file,'w+') as file_w:
            for temp_list in sorted(dictionary.values(), key=lambda value:value[4][5]):
                if temp_list[2] == "y":
                    pattern = self.format_pattern_ads_sites(temp_list[0], # header
                                                            temp_list[1], # rule
                                                            temp_list[2], # http
                                                            temp_list[3], # tls
                                                            temp_list[4]) # guid
                elif temp_list[3] == "y":
                    pattern = self.format_pattern_sites(temp_list[0], # header
                                                        temp_list[1], # rule
                                                        temp_list[2], # http
                                                        temp_list[3], # tls
                                                        temp_list[4]) # guid
                file_w.write(pattern + "\n");
        guids_f.close()
        rules_f.close()
        file_w.close();
    